package com.cxyd.modules.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.common.utils.ConvertUtils;
import com.cxyd.common.utils.ProcResult;
import com.cxyd.modules.api.dao.CallbackDao;
import com.cxyd.modules.api.dto.CallbackDTO;
import com.cxyd.modules.api.entity.CallbackEntity;
import com.cxyd.modules.api.service.CallbackService;
import com.cxyd.modules.wms.dao.*;
import com.cxyd.modules.wms.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class CallbackServiceImpl extends CrudServiceImpl<CallbackDao, CallbackEntity, CallbackDTO> implements CallbackService {
    final TaskDao taskDao;
    final LocateDao locateDao;
    final StockDao stockDao;
    final PostWcsDao postWcsDao;
    final PurchaseDetailDao purchaseDetailDao;
    final OrderReelDao orderReelDao;

    public CallbackServiceImpl(TaskDao taskDao, LocateDao locateDao, StockDao stockDao, PostWcsDao postWcsDao, PurchaseDetailDao purchaseDetailDao, OrderReelDao orderReelDao) {
        this.taskDao = taskDao;
        this.locateDao = locateDao;
        this.stockDao = stockDao;
        this.postWcsDao = postWcsDao;
        this.purchaseDetailDao = purchaseDetailDao;
        this.orderReelDao = orderReelDao;
    }


    @Override
    public QueryWrapper<CallbackEntity> getWrapper(Map<String, Object> params) {
        return null;
    }

    @Override
    public CallbackDTO getOneByPk(Map<String, Object> params) {
            String requestPk = (String) params.get("requestPk");
            String noticeType = (String) params.get("noticeType");
            final CallbackEntity entity = baseDao.getOneByPk(requestPk,noticeType);
            return ConvertUtils.sourceToTarget(entity, CallbackDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProcResult callbackHandle(Map<String, Object> params) {
        ProcResult result= new ProcResult();
        final String requestPk = (String) params.get("requestPk");
        if (StringUtils.isBlank(requestPk)) {
            return new ProcResult().result("123", "[requestPk]不能为空!");
        }
        //baseDao.callbackHandle(params);
        //根据托盘号获取任务
        String contNo = (String) params.get("contNo");
        String noticeType = (String) params.get("noticeType");
        String curPos = (String) params.get("curPos");
        String noticeTypeName = "";
        Date now = new Date();

        try {

            List<TaskEntity> taskList = taskDao.selectList(new QueryWrapper<TaskEntity>()
                    .eq("cont_no",contNo)
                    .eq("to_position",curPos)
                    .eq("task_st",1));
            if(taskList.size()==0){
                throw new Exception("料箱没有任务");
            }
            TaskEntity taskEntity = taskList.get(0);
            String toLc = taskEntity.getToPosition();
            String fromLc = taskEntity.getFromPosition();

            //判断货位的类型
            String toLocateType = locateDao.selectOne(new QueryWrapper<LocateEntity>()
                    .eq("locate_no",toLc)).getLocateType();

            String fromLocateType = locateDao.selectOne(new QueryWrapper<LocateEntity>()
                    .eq("locate_no",fromLc)).getLocateType();

            /*之前取任务判断出入库，会存在问题，因为出库任务没卡住，同时存在出入库任务，
             所以按WCS的当前位置判断出入库 20250416*/
            String curLocateType = locateDao.selectOne(new QueryWrapper<LocateEntity>()
                    .eq("locate_no",curPos)).getLocateType();

            if(noticeType.equals("2"))
            {
                //上架/到达
                //更新任务当前位置和状态
                //更新库存当前位置
                //上架需要更新货位状态和托盘号，到达不需要，根据至货位toLc判断是下架还是到达
                UpdateWrapper<TaskEntity> updateTaskWrapper = new UpdateWrapper<>();
                updateTaskWrapper.eq("cont_no",contNo)
                        .eq("task_st",1)
                        .set("current_position", toLc)
                        .set("task_st", 2);
                taskDao.update(null,updateTaskWrapper);//更新任务

                UpdateWrapper<StockEntity> updateStockWrapper = new UpdateWrapper<>();
                updateStockWrapper.eq("cont_no",contNo)
                        .set("cur_position", toLc);
                stockDao.update(null,updateStockWrapper);//更新库存
                noticeTypeName = "到达目的";

                /*之前取任务判断出入库，会存在问题，因为出库任务没卡住，同时存在出入库任务，
                 所以按WCS的当前位置判断出入库 20250416*/
                if(!curLocateType.equals("HW"))//if(fromLocateType.equals("HW"))
                {
                    //出库
                    UpdateWrapper<LocateEntity> updateLocateWrapper = new UpdateWrapper<>();
                    updateLocateWrapper.eq("locate_no",fromLc)
                            .eq("cont_no",contNo)
                            .set("locate_st", 0)
                            .set("cont_no","");
                    locateDao.update(null,updateLocateWrapper);//更新货位状态空闲+托盘致空

                    //删除WCS任务
                    postWcsDao.delete(new QueryWrapper<PostWcsEntity>()
                            .eq("cont_no",contNo));

                }

                /*之前取任务判断出入库，会存在问题，因为出库任务没卡住，同时存在出入库任务，
                 所以按WCS的当前位置判断出入库 20250416*/
                if(curLocateType.equals("HW"))//if(toLocateType.equals("HW"))
                {
                    noticeTypeName = "上架";
                    //上架
                    UpdateWrapper<LocateEntity> updateLocateWrapper = new UpdateWrapper<>();
                    updateLocateWrapper.eq("locate_no",toLc)
                            .set("locate_st", 2)
                            .set("cont_no",contNo);
                    locateDao.update(null,updateLocateWrapper);//更新货位

                    //删除WCS任务
                    postWcsDao.delete(new QueryWrapper<PostWcsEntity>()
                            .eq("cont_no",contNo));

                    //做入库单的更新
                    try
                    {
                        if(stockDao.exists(new QueryWrapper<StockEntity>()
                                .eq("cont_no",contNo)) &&
                                purchaseDetailDao.exists(new QueryWrapper<PurchaseDetailEntity>()
                                        .eq("cont_no",contNo)
                                        .eq("order_row_no","0")
                                        .eq("detail_st",0)))
                        {
                            List<StockEntity> inveList = stockDao.selectList(new QueryWrapper<StockEntity>()
                                    .eq("cont_no",contNo));
                            for (StockEntity inve : inveList
                            ) {

                                try
                                {
                                    PurchaseDetailEntity updatePd = purchaseDetailDao.selectOne(new QueryWrapper<PurchaseDetailEntity>()
                                            .eq("cont_no",contNo)
                                            .eq("order_row_no","0")
                                            .eq("detail_st",0));
                                    updatePd.setOrderRowNo("1");
                                    updatePd.setUpdateDate(now);
                                    purchaseDetailDao.updateById(updatePd);

                                }
                                catch (Exception ex)
                                {
                                    //不做处理
                                }

                            }

                        }
                    }
                    catch (Exception ex)
                    {
                        //不做处理

                    }

                    //如果有出库任务，再生成
                    if(orderReelDao.exists(new QueryWrapper<OrderReelEntity>()
                            .eq("cont_no",contNo)
                            .eq("detail_st",0)))
                    {
                        try
                        {
                            String dvcNo = locateDao.selectOne(new QueryWrapper<LocateEntity>()
                                    .eq("locate_no",toLc)).getDvcNo();

                            String toLocateNew = locateDao.selectOne(new QueryWrapper<LocateEntity>()
                                    .eq("locate_type","STS")
                                    .eq("active",1)
                                    .eq("dvc_no",dvcNo)).getLocateNo();//操作货位;
                            OrderReelEntity reel = orderReelDao.selectList(new QueryWrapper<OrderReelEntity>()
                                    .eq("cont_no",contNo)
                                    .eq("detail_st",0)).get(0);
                            String zll = reel.getZllbh();

                            String comm = "";
                            String prty = "";
                            if(zll==null||zll.isEmpty())
                            {
                                comm = "料箱零星出庫";
                                prty = "3";
                            }
                            else
                            {
                                comm = "料箱工单出库";
                                prty = "1";
                            }

                            TaskEntity taskNew = new TaskEntity();

                            taskNew.setTaskType("02");
                            taskNew.setTaskSubType("021");
                            taskNew.setContNo(contNo);
                            taskNew.setComments(comm);
                            taskNew.setTaskSt(1);
                            taskNew.setFromPosition(toLc);
                            taskNew.setCurrentPosition(toLc);
                            taskNew.setToPosition(toLocateNew);
                            taskNew.setCreateDate(now);
                            taskNew.setUpdateDate(now);
                            taskNew.setCreator(reel.getCreator());
                            taskNew.setUpdater(reel.getCreator());

                            taskDao.insert(taskNew);

                            //wms_post_wcs下发设备任务
                            String contType = contNo.charAt(0)=='B'?"2":"1";
                            PostWcsEntity postWcsEntity = new PostWcsEntity();
                            postWcsEntity.setContNo(contNo);
                            postWcsEntity.setRequestPk(UUID.randomUUID().toString().replace("-",""));
                            postWcsEntity.setContType(contType);
                            postWcsEntity.setFrmPos(toLc);
                            postWcsEntity.setCurPos(toLc);
                            postWcsEntity.setToPos(toLocateNew);
                            postWcsEntity.setTrkType("OT");
                            postWcsEntity.setTrkPrty(prty);
                            postWcsEntity.setCreateDate(now);
                            postWcsEntity.setUpdateDate(now);
                            postWcsEntity.setCreator(reel.getCreator());
                            postWcsEntity.setUpdater(reel.getCreator());
                            postWcsDao.insert(postWcsEntity);

                        }
                        catch (Exception ex)
                        {

                        }
                    }

                }
                //删除WCS任务
//                postWcsDao.delete(new QueryWrapper<PostWcsEntity>()
//                        .eq("cont_no",contNo));

            }
            else if(noticeType.equals("1"))
            {
                noticeTypeName = "下架";
                //下架
                UpdateWrapper<TaskEntity> updateTaskWrapper = new UpdateWrapper<>();
                updateTaskWrapper.eq("cont_no",contNo)
                        .eq("task_st",1)
                        .set("current_position", curPos);
                taskDao.update(null,updateTaskWrapper);//更新任务

                UpdateWrapper<StockEntity> updateStockWrapper = new UpdateWrapper<>();
                updateStockWrapper.eq("cont_no",contNo)
                        .set("cur_position", curPos);
                stockDao.update(null,updateStockWrapper);//更新库存当前位置

                if(!curLocateType.equals("HW"))//if(fromLocateType.equals("HW"))
                {
                    UpdateWrapper<LocateEntity> updateLocateWrapper = new UpdateWrapper<>();
                    updateLocateWrapper.eq("locate_no",fromLc)
                            .eq("cont_no",contNo)
                            .set("locate_st", 0)
                            .set("cont_no","");
                    locateDao.update(null,updateLocateWrapper);//更新货位状态空闲+托盘致空

                }
            }
            else
            {
                throw new Exception("通知类型不正确");
            }

            result.setCode("0");
            result.setMsg(noticeTypeName+"处理成功");

        }
        catch (Exception ex)
        {
            result.setCode("-1");
            result.setMsg(ex.getMessage());
        }

        return result;
    }
}
